x86: put_superpage() must also work for !opt_allow_superpage
authorKeir Fraser <keir.fraser@citrix.com>
Tue, 15 Jun 2010 12:20:43 +0000 (13:20 +0100)
committerKeir Fraser <keir.fraser@citrix.com>
Tue, 15 Jun 2010 12:20:43 +0000 (13:20 +0100)
This is because the P2M table, when placed at a kernel specified
location, gets populated with large pages, which the domain must have
a way to unmap/recycle.

Additionally when allowing Dom0 to use superpages, they ought to be
tracked accordingly in the superpage frame table.

Signed-off-by: Jan Beulich <jbeulich@novell.com>
xen/arch/x86/domain_build.c
xen/arch/x86/mm.c
xen/include/asm-x86/mm.h

index 166509f2e20bd87c3327929c87413bdcb45c41af..3995897e5bc15e0d3bf2c37882af744b68b16001 100644 (file)
@@ -914,6 +914,8 @@ int __init construct_dom0(
                 {
                     *l2tab = l2e_from_page(page,
                                            L1_PROT|_PAGE_DIRTY|_PAGE_PSE);
+                    if ( opt_allow_superpage )
+                        get_superpage(page_to_mfn(page), d);
                     va += 1UL << L2_PAGETABLE_SHIFT;
                     continue;
                 }
index 6256e0d02722d2abe12c472f111a56f61a125a85..dcfb7a682a18c5f8b06afb87dbef7dbcd97ada00 100644 (file)
@@ -155,7 +155,9 @@ unsigned long __read_mostly pdx_group_valid[BITS_TO_LONGS(
 int opt_allow_superpage;
 boolean_param("allowsuperpage", opt_allow_superpage);
 
+#ifdef __i386__
 static int get_superpage(unsigned long mfn, struct domain *d);
+#endif
 static void put_superpage(unsigned long mfn);
 
 #define l1_disallow_mask(d)                                     \
@@ -2568,7 +2570,7 @@ void clear_superpage_mark(struct page_info *page)
 
 }
 
-static int get_superpage(unsigned long mfn, struct domain *d)
+int get_superpage(unsigned long mfn, struct domain *d)
 {
     struct spage_info *spage;
     unsigned long x, nx, y;
@@ -2611,7 +2613,11 @@ static void put_superpage(unsigned long mfn)
     unsigned long x, nx, y;
     unsigned long do_pages = 0;
 
-    ASSERT(opt_allow_superpage);
+    if ( !opt_allow_superpage )
+    {
+        put_spage_pages(mfn_to_page(mfn));
+        return;
+    }
 
     spage = mfn_to_spage(mfn);
     y = spage->type_info;
index f1d6c8dc1cb598507726543a855f0d1f4b49a01a..2005b7be9563651d14bee75b884a80959274faea 100644 (file)
@@ -281,6 +281,7 @@ extern void share_xen_page_with_privileged_guests(
 #define frame_table ((struct page_info *)FRAMETABLE_VIRT_START)
 #ifdef __x86_64__
 #define spage_table ((struct spage_info *)SPAGETABLE_VIRT_START)
+int get_superpage(unsigned long mfn, struct domain *d);
 #endif
 extern unsigned long max_page;
 extern unsigned long total_pages;